home *** CD-ROM | disk | FTP | other *** search
- (*************************************************************************
- :Program. BinDiff
- :Version. V1.1 (27.01.95)
- :Contents. see --background--
-
- :Author. Jan Hense [juh]
- :Address. Lothringerstr. 9/Rgb., 81667 München, Germany
- :Address. Tel. +49-89-4807104, e-mail j.hense@amc.insider.sub.de
- :Copyright. freely distributable
-
- :Language. Oberon (with Amiga Oberon extensions)
- :Translator. Amiga Oberon v3.00d
- **************************************************************************)
-
- MODULE BinDiff;
-
- IMPORT
-
- Break, Dos, Exec, Strings, SYSTEM;
-
-
- (*
- ******* BinDiff/--background-- *******************************************
- *
- * NAME
- *
- * BinDiff v1.1
- *
- * DESCRIPTION
- *
- * Compare two binary files in chunks of 8 bytes, dumping all
- * differing chunks. Differing bytes are marked. Line format is:
- *
- * offset: file1-hex file1-chars | file2-hex file2-chars
- *
- * If BinDiff finds any differences it sets WARN (5) as the DOS
- * error code, else OK (0). BinDiff is pure of heart and can
- * therefore be made resident.
- *
- * SYNOPSIS
- *
- * BinDiff FILE1/A,FILE2/A,HEX/S,ALL/S,QUIET/S
- *
- * OPTIONS
- *
- * FILE1, FILE2 - the two files to be compared
- * HEX - offsets are printed in hex not decimal
- * ALL - dump all, not only differing chunks
- * QUIET - all output is omitted
- *
- * COMPILING
- *
- * This program was written in Oberon-2 with Amiga Oberon extensions.
- * Compile and link it under Amiga Oberon v3.00 with
- *
- * oberon -amd BinDiff
- * olink -amd BinDiff
- *
- * To extract this documentation use Autodoc 2.7 by hartmut Goebel:
- *
- * autodoc -a -f BinDiff.mod > BinDiff.doc
- *
- * AUTHOR
- *
- * Jan Hense
- * Lothringerstr. 9/Rgb.
- * 81667 München, Germany
- * Tel. +49-89-4807104
- * e-mail j.hense@amc.insider.sub.de
- *
- * COPYRIGHT
- *
- * Copyright reserved by the author. Freely distributable.
- *
- **************************************************************************
- *
- *)
-
-
- (*
- ******* BinDiff/--history-- **********************************************
- *
- * v1.1 (27.01.95) [juh]
- *
- * bug: forgot Dos.FreeArgs()
- * slight changes in output format
- * new option: QUIET/S
- * added COMPILING in --background--
- * now sets WARN as DOS error code if any diffs were found
- *
- * v1.0 (07.01.95) [juh]
- *
- * Created initial version.
- *
- **************************************************************************
- *
- * TO DO
- *
- *)
-
-
- CONST
-
- template = "FILE1/A,FILE2/A,HEX/S,ALL/S,QUIET/S"
- "\o$VER: BinDiff 1.1 (27.01.95) ©1995 j.hense@amc.insider.sub.de";
-
- missingArgs = "BinDiff: arguments incomplete\n";
- noOpen = "BinDiff: couldn't open file '%s'\n";
- readError = "BinDiff: read error #%ld in file '%s'\n";
-
- longerThan = "File '%s' is longer than '%s'\n";
- diffsFound = "Differences found: %ld\n";
- noDiffsFound = "No differences found\n";
-
- emphasizeCSI = "\[33m";
- normalCSI = "\[0m";
- unprintable = "\[1m·\[0m";
- unprintableLen = 7+1;
-
- lineLength = 8;
-
-
- TYPE
-
- ArgsStruct = STRUCT (as: Dos.ArgsStruct)
- file1: Exec.STRPTR;
- file2: Exec.STRPTR;
- hex: LONGINT;
- all: LONGINT;
- quiet: LONGINT;
- END;
-
-
- VAR
-
- rda: Dos.RDArgsPtr;
- args: ArgsStruct;
- file1, file2: Dos.FileHandlePtr;
- quiet: BOOLEAN;
- totalDiffs: LONGINT;
- line1, line2: ARRAY lineLength+1 OF CHAR;
- len1, len2: LONGINT;
- err: LONGINT;
- offset: LONGINT;
- void: LONGINT;
-
-
-
-
- PROCEDURE DumpDiffedLine(VAR line1, line2: ARRAY OF CHAR;
- len: LONGINT);
-
- VAR
-
- n: LONGINT;
- c: CHAR;
- char: ARRAY unprintableLen OF CHAR;
-
- BEGIN
-
- FOR n := 0 TO len-1 DO
- c := line1[n];
- IF (c<" ") OR ((c>"~") & (c<"¡")) THEN
- COPY(unprintable, char);
- ELSE
- char[0] := c; char[1] := 0X;
- END;
- IF c#line2[n] THEN
- Dos.PrintF("%s%s%s",
- SYSTEM.ADR(emphasizeCSI),
- SYSTEM.ADR(char),
- SYSTEM.ADR(normalCSI));
- ELSE
- Dos.PrintF("%s", SYSTEM.ADR(char));
- END;
- (* IF (n MOD 4)=3 THEN Dos.PrintF(" "); END; *)
- END;
-
- (* fill up line *)
- FOR n := n TO lineLength-1 DO
- Dos.PrintF(" ");
- END;
-
- END DumpDiffedLine;
-
-
-
- PROCEDURE DumpDiffedLineHex(VAR line1, line2: ARRAY OF CHAR;
- len: LONGINT);
-
- VAR
-
- n: LONGINT;
-
- BEGIN
-
- FOR n := 0 TO len-1 DO
- IF line1[n]#line2[n] THEN
- Dos.PrintF("%s%02lx%s",
- SYSTEM.ADR(emphasizeCSI),
- ORD(line1[n]),
- SYSTEM.ADR(normalCSI));
- ELSE
- Dos.PrintF("%02lx", ORD(line1[n]));
- END;
- IF (n MOD 4)=3 THEN Dos.PrintF(" "); END;
- END;
-
- (* fill up line *)
- FOR n := n TO lineLength-1 DO
- Dos.PrintF(" ");
- IF (n MOD 4)=3 THEN Dos.PrintF(" "); END;
- END;
-
- END DumpDiffedLineHex;
-
-
-
- PROCEDURE CompareTwoLines(offset: LONGINT;
- VAR line1, line2: ARRAY OF CHAR;
- len1, len2: LONGINT);
-
- VAR
-
- len, n, d: LONGINT;
-
- BEGIN
-
- IF len1<len2 THEN len := len1; ELSE len := len2; END;
-
- (* are there any diffs? *)
- FOR n := 0 TO len-1 DO
- IF line1[n]#line2[n] THEN INC(d); END;
- END;
- INC(totalDiffs, d);
- IF quiet OR ((d=0) & (args.all=0)) (* only differing lines *) THEN
- RETURN;
- END;
-
- IF args.hex=0 THEN
- Dos.PrintF("%08ld: ", offset);
- ELSE
- Dos.PrintF("%08lx: ", offset);
- END;
-
- DumpDiffedLineHex(line1, line2, len);
- Dos.PrintF(" ");
- DumpDiffedLine(line1, line2, len);
-
- Dos.PrintF(" | ");
-
- DumpDiffedLineHex(line2, line1, len);
- Dos.PrintF(" ");
- DumpDiffedLine(line2, line1, len);
-
- Dos.PrintF("\n");
-
- END CompareTwoLines;
-
-
-
- BEGIN
-
- rda := Dos.ReadArgs(template, args, NIL);
- quiet := (args.quiet#0);
- IF rda = NIL THEN
- IF ~quiet THEN Dos.PrintF(missingArgs); END;
- HALT(10);
- END;
-
- file1 := Dos.Open(args.file1^, Dos.oldFile);
- IF file1=NIL THEN
- IF ~quiet THEN Dos.PrintF(noOpen, args.file1); END;
- HALT(10);
- END;
-
- file2 := Dos.Open(args.file2^, Dos.oldFile);
- IF file2=NIL THEN
- IF ~quiet THEN Dos.PrintF(noOpen, args.file2); END;
- HALT(10);
- END;
-
- totalDiffs := 0;
- offset := 0;
- void := Dos.SetIoErr(0); (* FRead() doesn't clear IoErr *)
- LOOP
-
- len1 := Dos.FRead(file1, line1, 1, lineLength);
- err := Dos.SetIoErr(0);
- IF err>0 THEN
- IF ~quiet THEN Dos.PrintF(readError, err, args.file1); END;
- HALT(10);
- END;
-
- len2 := Dos.FRead(file2, line2, 1, lineLength);
- err := Dos.SetIoErr(0);
- IF err>0 THEN
- IF ~quiet THEN Dos.PrintF(readError, err, args.file2); END;
- HALT(10);
- END;
-
- IF (len1=0) OR (len2=0) THEN (* EOF *)
- EXIT;
- END;
-
- CompareTwoLines(offset, line1, line2, len1, len2);
-
- IF len1#len2 THEN (* EOF in next read *)
- EXIT;
- END;
-
- INC(offset, len1);
-
- END;
-
- IF ~quiet THEN
-
- IF len1>len2 THEN
- Dos.PrintF(longerThan, args.file1, args.file2);
- ELSIF len2>len1 THEN
- Dos.PrintF(longerThan, args.file2, args.file1);
- END;
-
- IF totalDiffs>0 THEN
- Dos.PrintF(diffsFound, totalDiffs);
- ELSE
- Dos.PrintF(noDiffsFound);
- END;
-
- END;
-
- IF totalDiffs>0 THEN
- HALT(5); (* DOS return code = WARN *)
- END; (* don't append code after this line! *)
-
- CLOSE
-
- IF ~quiet THEN Dos.PrintF(normalCSI); (* in case of user break *) END;
- IF file1#NIL THEN Dos.OldClose(file1); END;
- IF file2#NIL THEN Dos.OldClose(file2); END;
- Dos.FreeArgs(rda);
-
- END BinDiff.
-